﻿using System;
using System.Reflection;

namespace Schedulr.Tools
{
    /// <summary>
    /// Specifies the milestone version of an assembly, e.g. "2.0 RTM" or "3.5 Beta 2".
    /// </summary>
    [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
    public sealed class AssemblyMilestoneAttribute : Attribute
    {
        #region Fields

        /// <summary>
        /// The milestone version of the assembly.
        /// </summary>
        private readonly string milestone;

        #endregion

        #region Milestone Property

        /// <summary>
        /// Gets the milestone version of the assembly.
        /// </summary>
        public string Milestone
        {
            get
            {
                return this.milestone;
            }
        }

        #endregion

        #region Constructor

        /// <summary>
        /// Initializes a new instance of the <see cref="T:AssemblyMilestoneAttribute"/> class.
        /// </summary>
        /// <param name="milestone">The milestone version of the assembly.</param>
        public AssemblyMilestoneAttribute(string milestone)
        {
            this.milestone = milestone;
        }

        #endregion

        #region Static GetMilestoneFromAssembly Method

        /// <summary>
        /// Gets the milestone version from the calling assembly.
        /// </summary>
        /// <returns>The milestone version of the assembly calling this method.</returns>
        /// <exception cref="ArgumentException">The assembly does not have the AssemblyMilestoneAttribute defined.</exception>
        public static string GetMilestoneFromAssembly()
        {
            return GetMilestoneFromAssembly(Assembly.GetCallingAssembly());
        }

        /// <summary>
        /// Gets the milestone version from the given assembly.
        /// </summary>
        /// <returns>The milestone version of the given assembly.</returns>
        /// <exception cref="ArgumentException">The assembly does not have the AssemblyMilestoneAttribute defined.</exception>
        public static string GetMilestoneFromAssembly(Assembly assembly)
        {
            if (assembly == null)
            {
                throw new ArgumentNullException("assembly");
            }

            AssemblyMilestoneAttribute[] milestoneAttributes = (AssemblyMilestoneAttribute[])assembly.GetCustomAttributes(typeof(AssemblyMilestoneAttribute), false);
            if (milestoneAttributes.Length == 0)
            {
                throw new ArgumentException("The assembly does not have the AssemblyMilestoneAttribute defined:" + assembly.FullName);
            }

            return milestoneAttributes[0].Milestone;
        }

        #endregion
    }
}